//! Razne funkcije koje (jos) ne potpadaju nigdje drugdje

#ifndef	_J_RAZNO_H_
#define	_J_RAZNO_H_

#include "tipovi.h"
#include <arh/razno.h>

void	*memset (void *s, int c, size_t n);
void	*memsetw (void *s, int c, size_t n);
void	*memcpy (void *dest, const void *src, size_t n);
void	*memmove (void *dest, const void *src, size_t n);
void	*memmovew (void *dest, const void *src, size_t n);

// translatiraj neke arh pozive
#define	j_zaustavi()			arh_zaustavi()
#define	j_zaustavi_potpuno(p)		arh_zaustavi_potpuno(p)
#define	j_dozvoli_prekidanje()		arh_prekidi_dozvoli_prekidanje()
#define	j_zabrani_prekidanje()		arh_prekidi_zabrani_prekidanje()
#define	j_dozvoli_prekide(p)		arh_dozvoli_prekide(p)

#define	j_generiraj_prekid(p)		arh_generiraj_prekid(p)
#define	j_programski_prekid()		arh_generiraj_prekid(PREKIDI_PROGRAMSKI)

//kada parametar ne smije biti NULL - provjeri i vrati -1, ako je NULL
#define PARAMNULL(p)					\
	if ((p) == NULL) {				\
		j_ispisi("Parametar je NULL\n");	\
		return -1;				\
	}

//pretrazivanje bitova
#define bit_scan_forward32(i)	bit_scan_forward_asm32(i)
#define bit_scan_backward32(i)	bit_scan_backward_asm32(i)


/* Malo drukcije upravljanje slobodnim/zauzetim elementima polja sa maskom

Maska je hijerarhijski izgradjena (stablasta struktura)

Npr. ako bi imali rijec od 4 bita

[0100][1111][0011][0000]	- 1. razina -	16 elemenata polja mogu se
    \    \    /     /				oznaciti: slobodna ili zauzeta
     \___ \  /  ___/				npr. 1 - slobodna, 0 - zauzeta
         \ || /
         [1110]			- 2. razina -	pojedini bit oznacava da li u
						odgovarajucoj grani ima bar
						jedna jedinica
Za 32 bita:
razina k  : 32 bita - [xxx...xx]
razina k-1: za svaki bit preth. razine po 32 bita (ako treba) [32x32 bita]
itd.
Najveci broj razina je 7 = najveci 32 bitni broj (kao indeks) je: 2^32-1 < 32^7

U zadnjoj je ("korisnoj") razini prava maska sa po jednim bitom za svaki element
polja; bit 1 oznacava da je element slobodan (nekoristen), 0 da je u uporabi
(ili obrnuto kada tako treba).

Ostale razine (prije zadnje) su samo pomoc da se brze dodje do bita, da se ne
pretrazuje slijedno element po element - smanjuje se slozenost sa linearne O(N)
na log. O(log N) (logaritam po bazi 32).


Pri postavljanju/brisanju/trazenju bita, koristi se logika koji broj bita 'bit'
rastavlja po bazi 2^x (x = 5 za 32-bitni int => baza je 32):

bit = A[k]*(2^x)^k + A[k-1]*(2^x)^(k-1) + ... + A[0]

broj 'bit' dijeli se u blokove po 5 bitova => to su A[i]

Npr. ako je indeks bit = 7654 = 1110111100110(2) = 00111 01111 00110
						    A[2]  A[1]  A[0]
						    = 7   = 15  = 6
Iz "korijena" ce se gledati 7. bit, iz iduce razine uzet ce se sedma grana i u
njoj gledati 15. bit; iz najnize razine gledati ce se: (7*32+15)-ta grana i u 
njoj 6. bit. (gledati ili postaviti ili brisati)


A[i] kaze koji bit u i-toj razini treba mijenajti u odabranom elementu 
definiranom u A[i+1] (osim ako je i = k tada se mijenja bit u A[k])

Za koji najmanji 'k' je A[k] != 0 ?  br_razina = k+1

Neka je 'vel' broj elemenata polja za koje se maska koristi (ne broj elemenata
pomocnog polja za maski!)
Po poziciji najznacajnijeg bita u 'vel' se moze odrediti broj razina:

br_razina = 1 + index_MSB(vel - 1) / 5; //scan backward

Uzima se 'vel-1' jer ako je vel = (2^5)^n dovoljno je n razina.
Npr. za vel = 32 = (2^5)^1 dovoljna je jedna razina (32-bitna mask), 
ali za 33 trebaju dvije (1 + 5/5 = 2)

broj elemenata za masku (priblizno, tocno je u makrou ispod):
	N/32^1	+ N/32^2 + ... + N/32^7
	zadnja	predzadnja (itd)
	razina	razina
*/

//slijedeci su define-ovi SAMO za preprocesor (izracun elemenata za masku)
//npr. kad se definira:		neki_tip j_nesto[N];
//tada za masku treba navesti:	MASKA(j_nesto, N);

#define BS_RAZ(N)	( ((N - 1) >> 5) > 0 ? ((N - 1) >> 5) + 1 : 0)
#define VELMASKE(E)	\
( \
	1 + BS_RAZ(E)							+ \
	BS_RAZ(BS_RAZ(E))						+ \
	BS_RAZ(BS_RAZ(BS_RAZ(E)))					+ \
	BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(E))))				+ \
	BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(E)))))			+ \
	BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(E))))))		+ \
	BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(BS_RAZ(E)))))))	  \
)

#ifdef KORISTI_MASKE
#define MASKA(J, N)	\
static uint32 m ## J[VELMASKE(N)] = {[0 ... (VELMASKE(N)-1)] = 0xffffffff};
#endif				//[gcc] polje se inicijalizira s jedinicama

int pronadji_bit_32(uint32 *polje, uint32 vel);
int postavi_bit_32 (uint32 *p, uint32 vel, uint32 bit, bool postavi);

#endif	/* _J_RAZNO_H_ */
